package com.daxt.service.impl;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.daxt.base.common.util.RedisUtil;
import com.daxt.common.config.minio.MinIoUtil;
import com.daxt.common.exception.BaseException;
import com.daxt.common.result.Result;
import com.daxt.common.result.ResultCode;
import com.daxt.common.result.ResultUtil;
import com.daxt.common.util.DateUtil;
import com.daxt.common.util.OcrUtil;
import com.daxt.mapper.archives.*;
import com.daxt.mapper.sys.*;
import com.daxt.model.constant.BaseConstants;
import com.daxt.model.constant.DicType;
import com.daxt.model.constant.FileExt;
import com.daxt.model.dic.*;
import com.daxt.model.dto.ArchivesStatisticsParamDto;
import com.daxt.model.dto.BaseExportParam;
import com.daxt.model.dto.BaseQueryDto;
import com.daxt.model.dto.Classifys;
import com.daxt.model.service.archives.param.GenCategoryNum;
import com.daxt.model.service.archives.vo.*;
import com.daxt.model.service.base.result.UserInfo;
import com.daxt.model.service.base.vo.BaseUser;
import com.daxt.model.service.base.vo.Dept;
import com.daxt.model.service.base.vo.Dic;
import com.daxt.model.service.select.ExportParam;
import com.daxt.model.xml.oa.AccessoryXml;
import com.daxt.model.xml.oa.StepXML;
import com.daxt.service.ArchivesService;
import com.daxt.service.DocService;
import com.daxt.service.FondsListService;
import com.daxt.service.UploadService;
import com.daxt.utils.*;
import com.daxt.utils.file.FileBaseUtil;
import com.daxt.utils.file.PdfUtils;
import com.google.common.base.Joiner;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Service
public class ArchivesServiceImpl extends ServiceImpl<ArchivesDocMapper, ArchivesDoc> implements ArchivesService {

    private static final Log log = LogFactory.getLog(ArchivesService.class);

    @Autowired
    private ArchivesTypeMapper archivesTypeMapper;
    @Autowired
    private FondsListService fondsListService;
    @Autowired
    private UserClassifyMapper userClassifyMapper;
    @Autowired
    private DicMapper dicMapper;
    @Autowired
    private ArchivesStatisticsMapper archivesStatisticsMapper;
    @Autowired
    private ArchivesDocMapper archivesDocMapper;
    @Autowired
    private ArchivesClassMapper archivesClassMapper;
    @Autowired
    private ArchivesDocFileMapper archivesDocFileMapper;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private ArchivesFondsMapper archivesFondsMapper;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private ArchivesTypeDocMapper archivesTypeDocMapper;
    @Autowired
    private ArchivesTestingFourMapper archivesTestingFourMapper;
    @Autowired
    private ArchivesTestingFourMetadataMapper archivesTestingFourMetadataMapper;
    @Autowired
    private ArchivesTestingFourRecordMapper archivesTestingFourRecordMapper;
    @Autowired
    private MinIoUtil minIoUtil;
    @Autowired
    private ArchivesDurableFileMapper archivesDurableFileMapper;
    @Autowired
    ArchivesBehaveLogMapper archivesBehaveLogMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DeptMapper deptMapper;

    @Override
    public Map<String, String> gainMetadataEditField(Long typeId, String fileType) {
        QueryWrapper<ArchivesTypeDoc> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("typeId",typeId);
        queryWrapper.eq("extType",fileType);
        queryWrapper.eq("isEdit","1");
        List<ArchivesTypeDoc> typeDocList = archivesTypeDocMapper.selectList(queryWrapper);
        Map<String,String> typeDocMap=new HashMap<>();
        for(ArchivesTypeDoc typeDoc:typeDocList){
            typeDocMap.put(typeDoc.getExtColumn(),typeDoc.getColumnComment());
        }
        return typeDocMap;
    }

    @Override
    public String saveArchivesDurableFile(List<String> ids,String fondsId,String typeId,String classId,String fileType) {

        //存储模式
        String accType = RedisUtil.getSysConfig(SystemConfigType.ACCESSORY_TYPE);

        BigDecimal docTotalSize = new BigDecimal(0d);


        if("doc".equals(fileType)){
            Map<Long,String> itemNumMap=new HashMap<>();
            QueryWrapper<ArchivesDoc> docQueryWrapper=new QueryWrapper<>();
            docQueryWrapper.select("id,itemNum");
            docQueryWrapper.in("id",ids);
            List<ArchivesDoc> docList =  archivesDocMapper.selectList(docQueryWrapper);
            for(ArchivesDoc doc: docList){
                itemNumMap.put(doc.getId(),doc.getItemNum());
            }

            QueryWrapper<ArchivesDocFile> docFileQueryWrapper=new QueryWrapper<>();
            docFileQueryWrapper.in("docId",ids);
            List<ArchivesDocFile> docFileList = archivesDocFileMapper.selectList(docFileQueryWrapper);
            for(ArchivesDocFile docFile:docFileList){
                String url=docFile.getFileUrl().replace(BaseConstants.BUCKET_NAME,"");

                String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);

                StringBuilder durableUrl=builderDurableUrl(fondsId,typeId,classId,itemNumMap.get(docFile.getDocId()),null);
                File fileMkdirs=new File(durableUrl.toString());
                if (!fileMkdirs.isDirectory()) fileMkdirs.mkdirs();
                durableUrl.append("/").append(docFile.getFileName());
                File downFile = new File(durableUrl.toString());
                try {
                    if (accType.equals(AccessoryType.TYPE_1.getKey())) {
                        FileUtils.copyFile(new File(ossDir + "static/" + url), downFile);// downFile(url,);
                    } else if (accType.equals(AccessoryType.TYPE_2.getKey())) {
                        InputStream inputStream = minIoUtil.download(url, BaseConstants.BUCKET_NAME);
                        if(inputStream==null){
                            return null;
                        }
                        FileBaseUtil.inputStreamToFile(inputStream, downFile);
                    }
                    long fLength = downFile.length();
                    Double i = fLength / 1024.0;//kb
                    BigDecimal fileLength = new BigDecimal(i.toString());
                    docTotalSize = docTotalSize.add(fileLength.setScale(0, BigDecimal.ROUND_HALF_UP));
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new BaseException(ResultCode.RESULT_ERROR.getCode(), "获取文件失败");
                }
            }
            for (String id:ids){
                StringBuilder durableUrl=builderDurableUrl(fondsId,typeId,classId,itemNumMap.get(Long.parseLong(id)),null);
                ArchivesDurableFile durableFile=new ArchivesDurableFile();
                durableFile.setDocId(Long.parseLong(id));
                durableFile.setFileUrl(durableUrl.toString());
                archivesDurableFileMapper.insert(durableFile);
            }

        }else{

            Map<Long,String> dossierNumMap1=new HashMap<>();
            QueryWrapper<ArchivesDoc> docQueryWrapper=new QueryWrapper<>();
            docQueryWrapper.select("id,dossierNum");
            docQueryWrapper.in("id",ids);
            List<ArchivesDoc> docList1 =  archivesDocMapper.selectList(docQueryWrapper);
            for(ArchivesDoc doc: docList1){
                dossierNumMap1.put(doc.getId(),doc.getDossierNum());
            }

            for(String id:ids){
                QueryWrapper<ArchivesDoc> archivesDocQueryWrapper=new QueryWrapper<>();
                archivesDocQueryWrapper.select("id , dossierNum , itemNum");
                archivesDocQueryWrapper.eq("isDelete",0);
                archivesDocQueryWrapper.eq("fileType","doc");
                archivesDocQueryWrapper.eq("dossierId",id);
                List<ArchivesDoc> docList=archivesDocMapper.selectList(archivesDocQueryWrapper);
                List<Long> idList=new ArrayList<>();

                Map<Long,String> mapDossierNum=new HashMap<>();
                Map<Long,String> mapItemNum=new HashMap<>();
                for(ArchivesDoc doc:docList){
                    idList.add(doc.getId());
                    mapDossierNum.put(doc.getId(),doc.getDossierNum());
                    mapItemNum.put(doc.getId(),doc.getItemNum());

                }

                if(!idList.isEmpty()){
                    QueryWrapper<ArchivesDocFile> docFileQueryWrapper=new QueryWrapper<>();
                    docFileQueryWrapper.in("docId",idList);
                    List<ArchivesDocFile> docFileList = archivesDocFileMapper.selectList(docFileQueryWrapper);
                    for(ArchivesDocFile docFile:docFileList){

                        String url=docFile.getFileUrl().replace(BaseConstants.BUCKET_NAME,"");

                        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);

                        StringBuilder durableUrl=builderDurableUrl(fondsId,typeId,classId,mapDossierNum.get(docFile.getDocId()),mapItemNum.get(docFile.getDocId()));
                        File fileMkdirs=new File(durableUrl.toString());
                        if (!fileMkdirs.isDirectory()) fileMkdirs.mkdirs();
                        durableUrl.append("/").append(docFile.getFileName());
                        File downFile = new File(durableUrl.toString());
                        try {
                            if (accType.equals(AccessoryType.TYPE_1.getKey())) {
                                FileUtils.copyFile(new File(ossDir + "static/" + url), downFile);// downFile(url,);

                            } else if (accType.equals(AccessoryType.TYPE_2.getKey())) {
                                InputStream inputStream = minIoUtil.download(url, BaseConstants.BUCKET_NAME);
                                if(inputStream==null){
                                    return null;
                                }
                                FileBaseUtil.inputStreamToFile(inputStream, downFile);
                            }
                            long fLength = downFile.length();
                            Double i = fLength / 1024.0;//kb
                            BigDecimal fileLength = new BigDecimal(i.toString());
                            docTotalSize = docTotalSize.add(fileLength.setScale(0, BigDecimal.ROUND_HALF_UP));
                        } catch (IOException e) {
                            e.printStackTrace();
                            throw new BaseException(ResultCode.RESULT_ERROR.getCode(), "获取文件失败");
                        }
                    }
                }


                StringBuilder durableUrl=builderDurableUrl(fondsId,typeId,classId,dossierNumMap1.get(Long.parseLong(id)),null);
                ArchivesDurableFile durableFile=new ArchivesDurableFile();
                durableFile.setDocId(Long.parseLong(id));
                durableFile.setFileUrl(durableUrl.toString());
                archivesDurableFileMapper.insert(durableFile);

            }
        }
        return docTotalSize+"KB";
    }

    @Override
    public void createArchivesXml(List<String> ids, String fileType, Long userId, HttpServletRequest request,String docTotalSize) {

        String clientIp= IpUtil.getIP(request);
        String sysHomeIp = RedisUtil.getSysConfig(SystemConfigType.SYS_HOME)==null ? "":RedisUtil.getSysConfig(SystemConfigType.SYS_HOME);
        if(!sysHomeIp.equals("")) sysHomeIp=sysHomeIp.substring(7,sysHomeIp.lastIndexOf(":"));

        BaseUser baseUser = userMapper.selectById(userId);
        List<Dept> deptList=new ArrayList<>();
        if(baseUser.getDeptIds()!=null) deptList = deptMapper.getAllParentDept(baseUser.getDeptIds());
        String dept="";
        if(deptList.size()==2){
            dept=deptList.get(1).getDeptName();
        }else if(deptList.size() > 2){
            dept=deptList.get(1).getDeptName()+" "+deptList.get(deptList.size()-1).getDeptName();
        }

        //字典值
        QueryWrapper<Dic> dicQueryWrapper=new QueryWrapper<>();
        dicQueryWrapper.in("dicType","secret","docFrom","storagePeriod");
        List<Dic> dicList = dicMapper.selectList(dicQueryWrapper);
        Map<String,String> dicMap=new HashMap();
        Map<String,String> docFromMap=new HashMap();
        Map<String,String> storagePeriodMap=new HashMap<>();
        for(Dic dic : dicList){
            if("secret".equals(dic.getDicType())) dicMap.put(dic.getDicCode(),dic.getDicValue());
            if("docFrom".equals(dic.getDicType())) docFromMap.put(dic.getDicCode(),dic.getDicValue());
            if("storagePeriod".equals(dic.getDicType())) storagePeriodMap.put(dic.getDicCode(),dic.getDicValue());
        }


        try {
            for(String id:ids){

                Document doc = DocumentHelper.createDocument();// 创建一个Document实例
                Element root = doc.addElement("电子档案封装包");// 添加根节点

                Element element= root.addElement("封装包元数据");
                element.addElement("封装包类型").addText("原始封装性");
                element.addElement("封装包类型描述").addText("本长期保存包首次封装，包含案卷元数据、文件及其元数据，原始封装，未经修改。");
                element.addElement("封装次数").addText("1");
                element.addElement("封装包创建人").addText(baseUser.getRealName());
                element.addElement("封装包创建时间").addText(DateUtil.getCurrentTime());
                element.addElement("封装包创建单位").addText(dept);
                element.addElement("数据来源").addText("数字档案管理系统");
                element.addElement("服务器IP").addText(sysHomeIp);
                element.addElement("客户端IP").addText(clientIp);
                element.addElement("数字摘要值").addText(""); //制定规则

                // 在根节点下添加第一个子节点
                String rootElementName="案卷";
                if("doc".equals(fileType)){
                    rootElementName="文件";
                }
                Element oneChildElement= root.addElement("档案实体元数据");

                ArchivesDoc archivesDoc = archivesDocMapper.queryById(id);
                QueryWrapper<ArchivesTypeDoc> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("typeId",archivesDoc.getTypeId());
                queryWrapper.eq("extType",archivesDoc.getFileType());
                queryWrapper.orderByAsc("sort");
                List<ArchivesTypeDoc> typeDocList = archivesTypeDocMapper.selectList(queryWrapper);

                String dossStr = JSON.toJSONString(archivesDoc);
                Map mapDoss= JSON.parseObject(dossStr);

                oneChildElement.addElement("聚合层次").addText(rootElementName);
                for (ArchivesTypeDoc typeDoc:typeDocList){

                    String columnComment=typeDoc.getColumnComment();
                    String extColumn=mapDoss.get(typeDoc.getExtColumn())==null ? "":mapDoss.get(typeDoc.getExtColumn()).toString();

                    if("secret".equals(typeDoc.getExtColumn())){
                        extColumn=dicMap.get(extColumn)==null ?"":dicMap.get(extColumn);  //将密级数值换成字面意思
                    }else if ("docFrom".equals(typeDoc.getExtColumn())){
                        extColumn=docFromMap.get(extColumn)==null? "":docFromMap.get(extColumn);  //系统来源
                    }else if("remainDay".equals(typeDoc.getExtColumn())){
                        continue;
                    }else if("storagePeriod".equals(typeDoc.getExtColumn())){
                        extColumn=storagePeriodMap.get(extColumn)==null ? "":storagePeriodMap.get(extColumn);
                    }

                    //档案元数据
                    oneChildElement.addElement(columnComment)
                            .addText(extColumn);
                }
                oneChildElement.addElement("计算机文件大小").addText(docTotalSize==null ? "":docTotalSize);
                oneChildElement.addElement("组卷人").addText(baseUser.getRealName());
                oneChildElement.addElement("组卷时间").addText(DateUtil.getCurrentTime());


                QueryWrapper<ArchivesBehaveLog> queryWrapperLog1=new QueryWrapper<>();
                queryWrapperLog1.apply("FIND_IN_SET("+id+",docIds)");
                List<ArchivesBehaveLog> archivesBehaveLogList = archivesBehaveLogMapper.selectList(queryWrapperLog1);

                Element oneChildElement2= root.addElement("业务实体元数据");
                int k=1;
                for(ArchivesBehaveLog behaveLog : archivesBehaveLogList){
                    Element  behaveElement= oneChildElement2.addElement("业务行为描述"+k);
                    behaveElement.addElement("责任者层级").addText(behaveLog.getOperationByDept()==null ? "":behaveLog.getOperationByDept());
                    behaveElement.addElement("责任者标识码").addText(behaveLog.getOperationLoginName());
                    behaveElement.addElement("责任者名称").addText(behaveLog.getOperationBy()==null ? "":behaveLog.getOperationBy());
                    behaveElement.addElement("责任者职能").addText(behaveLog.getOperationByRole()==null ? "":behaveLog.getOperationByRole());
                    behaveElement.addElement("责任者联系方式").addText("");
                    behaveElement.addElement("业务行为").addText(behaveLog.getOperation()==null ? "":behaveLog.getOperation());
                    behaveElement.addElement("业务行为标识").addText(behaveLog.getOperationCode());
                    behaveElement.addElement("业务行为描述").addText(behaveLog.getDescription()==null ? "":behaveLog.getDescription());
                    behaveElement.addElement("行为时间").addText(behaveLog.getCreateTime()==null ? "":behaveLog.getCreateTime());
                    k++;
                }

                // 在根节点下添加第一个子节点
                if("dossier".equals(fileType)){
                    Element twoChildElement= root.addElement("卷内信息"); //.addAttribute("attr", "root two");

                    QueryWrapper<ArchivesTypeDoc> queryWrapperDoc=new QueryWrapper<>();
                    queryWrapperDoc.eq("typeId",archivesDoc.getTypeId());
                    queryWrapperDoc.eq("extType","doc");
                    queryWrapperDoc.orderByAsc("sort");
                    List<ArchivesTypeDoc> typeDocList2 = archivesTypeDocMapper.selectList(queryWrapper);
                    List<ArchivesDoc> archivesDocList = archivesDocMapper.queryByDossierId(id);
                    for(int i=0;i<archivesDocList.size();i++){
                        Element twoChildElementOne = twoChildElement.addElement("文件"+(i+1));

                        String docStr = JSON.toJSONString(archivesDocList.get(i));
                        Map mapDoc= JSON.parseObject(docStr);
                        for(ArchivesTypeDoc typeDoc:typeDocList2){
                            String columnComment=typeDoc.getColumnComment();
                            String extColumn=mapDoc.get(typeDoc.getExtColumn())==null ? "":mapDoc.get(typeDoc.getExtColumn()).toString();
                            if("secret".equals(typeDoc.getExtColumn())){
                                extColumn=dicMap.get(extColumn)==null ? "":dicMap.get(extColumn);  //将密级数值换成字面意思
                            }else if ("docFrom".equals(typeDoc.getExtColumn())){
                                extColumn=docFromMap.get(extColumn)==null ? "":docFromMap.get(extColumn);  //系统来源
                            }else if("remainDay".equals(typeDoc.getExtColumn())){
                                continue;
                            }else if("storagePeriod".equals(typeDoc.getExtColumn())){
                                extColumn=storagePeriodMap.get(extColumn)==null ? "":storagePeriodMap.get(extColumn);
                            }
                            twoChildElementOne.addElement(columnComment).addText(extColumn);

                        }

                        QueryWrapper<ArchivesBehaveLog> queryWrapperLog2=new QueryWrapper<>();
                        queryWrapperLog2.apply("FIND_IN_SET("+archivesDocList.get(i).getId()+",docIds)");
                        List<ArchivesBehaveLog> archivesBehaveLogList2 = archivesBehaveLogMapper.selectList(queryWrapperLog2);
                        Element  twoChildElementOne2= twoChildElementOne.addElement("业务实体元数据");
                        int l=1;
                        for(ArchivesBehaveLog behaveLog : archivesBehaveLogList2){
                            Element  behaveElement2= twoChildElementOne2.addElement("业务行为描述"+l);
                            behaveElement2.addElement("责任者层级").addText(behaveLog.getOperationByDept()==null ? "":behaveLog.getOperationByDept());
                            behaveElement2.addElement("责任者标识码").addText(behaveLog.getOperationLoginName());
                            behaveElement2.addElement("责任者名称").addText(behaveLog.getOperationBy()==null ? "":behaveLog.getOperationBy());
                            behaveElement2.addElement("责任者职能").addText(behaveLog.getOperationByRole()==null ? "":behaveLog.getOperationByRole());
                            behaveElement2.addElement("责任者联系方式").addText("");
                            behaveElement2.addElement("业务行为").addText(behaveLog.getOperation()==null ? "":behaveLog.getOperation());
                            behaveElement2.addElement("业务行为标识").addText(behaveLog.getOperationCode());
                            behaveElement2.addElement("业务行为描述").addText(behaveLog.getDescription()==null ? "":behaveLog.getDescription());
                            behaveElement2.addElement("行为时间").addText(behaveLog.getCreateTime()==null ? "":behaveLog.getCreateTime());
                            l++;
                        }
                    }
                }


                // 自定义xml样式
                OutputFormat format = new OutputFormat();
                format.setIndentSize(2);  // 行缩进
                format.setNewlines(true); // 一个结点为一行
                format.setTrimText(true); // 去重空格
                format.setPadText(true);
                format.setNewLineAfterDeclaration(false); // 放置xml文件中第二行为空白行

                // 输出xml文件
                String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);
                StringBuilder stringBuilder=builderDurableUrl(archivesDoc.getFondsId(),archivesDoc.getTypeId().toString(),
                        archivesDoc.getClassId().toString(),
                        archivesDoc.getFileType().equals("doc")? archivesDoc.getItemNum():archivesDoc.getDossierNum(),null);

                File fileMkdirs=new File(stringBuilder.toString());
                if (!fileMkdirs.isDirectory()) fileMkdirs.mkdirs();
                stringBuilder.append("/档案信息元数据.xml");

                File file=new File(stringBuilder.toString());
                XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);
                writer.write(doc);
                writer.close();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Result<String> importLqArchives(BaseExportParam exportParam) {

        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);
        String url=exportParam.getUrl();

        if (StringUtils.isEmpty(url)) return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "请先上传要导入的文件！！！", null);

        String fondsId = exportParam.getFondsId();
        if(StringUtils.isNotEmpty(fondsId)){
            ArchivesFonds fonds = archivesFondsMapper.selectById(fondsId);
            if(fonds==null) return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "全宗不存在", null);
        }
        String classId = exportParam.getClassId();
        if(StringUtils.isNotEmpty(classId)){
            ArchivesClass archivesClass = archivesClassMapper.selectById(classId);
            if(archivesClass==null) return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "分类不存在", null);
        }
        String typeId = exportParam.getTypeId();
        if(StringUtils.isNotEmpty(typeId)){
            ArchivesType type = archivesTypeMapper.selectById(typeId);
            if(type==null) return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "门类不存在", null);
        }

        exportParam.setUrl(ossDir + url);
        List<ArchivesDoc> excelList = FileBaseUtil.parseLqArchivesExcel(exportParam);

        for (ArchivesDoc aDoc : excelList) {
            archivesDocMapper.insert(aDoc);
        }

        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", null);

    }

    public Result<String> automationDossierItemNumNum(ArchivesType at, String fileType, String classId, String fondsId, List<String> ids){
        if("0".equals(at.getAutoDossierItemNum())){
            return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", null);
        }

        if ("dossier".equals(fileType)&&(StringUtils.isEmpty(at.getGenItemNum())||StringUtils.isEmpty(at.getGenDossierNum()))){
            return ResultUtil.error("1001","请配置案件号或案卷号的生成规则！");
        }
        if ("doc".equals(fileType)&&StringUtils.isEmpty(at.getGenItemNum())){
            return ResultUtil.error("1001","请配置案件号的生成规则！");
        }

        ArchivesClass archivesClass= archivesClassMapper.selectById(classId);

        List<String> states=new ArrayList<>();
        states.add("0");
        states.add("1");
        states.add("2");

        //判断卷号或件号是否存在重复
        QueryWrapper<ArchivesDoc> docWrapper = new QueryWrapper<ArchivesDoc>();
        /*docWrapper.select();
        docWrapper.eq("typeId",at.getId());
        docWrapper.eq("classId",classId);
        docWrapper.eq("isDelete",0);
        docWrapper.eq("fondsId",fondsId);
        docWrapper.eq("fileType",fileType);

        docWrapper.in("state",states);
        if("doc".equals(fileType)){
            docWrapper.select("itemNum,count(1) itemCount");
            docWrapper.eq("dossierId","0");
            docWrapper.eq("char_length(itemNum)",at.getGenItemNum());
            docWrapper.groupBy("itemNum");
            //maxWrapper.select("max(itemNum) as itemNum");
        }else {
            docWrapper.select("dossierNum,count(1) itemCount");
            docWrapper.eq("char_length(dossierNum)",at.getGenDossierNum());
            //docWrapper.select("max(dossierNum) as dossierNum");
            docWrapper.groupBy("dossierNum");
        }*/


        //获取当前分类下，缺失的件号或卷号
        docWrapper = new QueryWrapper<ArchivesDoc>();
        docWrapper.eq("typeId",at.getId());
        docWrapper.eq(StringUtils.isNotEmpty(classId),"classId",classId);
        docWrapper.eq("isDelete",0);
        docWrapper.eq("fondsId",fondsId);
        docWrapper.eq("fileType",fileType);
        docWrapper.in("state",states);
        docWrapper.notIn("id",ids);
        if("doc".equals(fileType)){
            docWrapper.select("itemNum");
            docWrapper.eq("dossierId","0");
            docWrapper.eq("char_length(itemNum)",at.getGenItemNum());
            docWrapper.orderByAsc("itemNum");
            //maxWrapper.select("max(itemNum) as itemNum");
        }else {
            docWrapper.select("dossierNum as itemNum");
            docWrapper.eq("char_length(dossierNum)",at.getGenDossierNum());
            docWrapper.orderByAsc("dossierNum");
            //docWrapper.select("max(dossierNum) as dossierNum");
        }
        List<ArchivesDoc> docNumList = archivesDocMapper.selectList(docWrapper);
        List<Integer> docNum=new ArrayList<>();
        List<Integer> lackNums=new ArrayList<>();
        for(int i=0;i<docNumList.size();i++){
            int num=Integer.parseInt(docNumList.get(i).getItemNum());
            docNum.add(num);
        }
        if(docNumList.size()>0){
            for(int i=0;i<docNum.get(docNumList.size()-1);i++){
                int j=i+1;
                boolean flag=false;
                for(int k=0;k<docNumList.size();k++){
                    int num=Integer.parseInt(docNumList.get(k).getItemNum());
                    if(j==num) {
                        flag=false;
                        break;
                    }
                    if(j!=num){
                        flag=true;
                    }
                }
                if(flag){
                    lackNums.add(j);
                }
            }
        }


        //获取最大值
        int maxItemNum=-1;
        int maxDossierNum=-1;
        //if(lackNums.size()>0){

        //}else{
            if(docNumList!=null && docNumList.size()>0){
                if("doc".equals(fileType)){
                    maxItemNum=Integer.parseInt(docNumList.get(docNumList.size()-1).getItemNum());
                }else{
                    maxDossierNum=Integer.parseInt(docNumList.get(docNumList.size()-1).getItemNum());;
                }
            }else{
                if("doc".equals(fileType)){
                    maxItemNum=0;
                }else{
                    maxDossierNum=0;
                }
            }
        //}

        for (int j=0;j<ids.size();j++) {
            String id=ids.get(j);
            ArchivesDoc doc = archivesDocMapper.selectById(id);
            int realItemNum;
            int realDossierNum;
            if(lackNums.size()>0 && j<lackNums.size()){
                realItemNum=lackNums.get(j);
                realDossierNum=lackNums.get(j);
            }else{
                //if(StringUtils.isNotEmpty(doc.getItemNum())){
                    //realItemNum=Integer.parseInt(doc.getItemNum());
                //}else {
                    realItemNum=++maxItemNum;
                //}
                //if(StringUtils.isNotEmpty(doc.getDossierNum())){
                    //realDossierNum=Integer.parseInt(doc.getDossierNum());
                //}else{
                    realDossierNum=++maxDossierNum;

                //}

            }


            //件处理逻辑
            if("doc".equals(fileType)){
                String itemNum=realItemNum+"";
                int genItemNum = Integer.parseInt(at.getGenItemNum());
                if (itemNum.length()<genItemNum){
                    int s=genItemNum-itemNum.length();
                    for (int i=0;i<s;i++){
                        itemNum="0"+itemNum;
                    }
                    doc.setItemNum(itemNum);
                }else{
                    doc.setItemNum(itemNum);
                }

            }else if("dossier".equals(fileType)){ //卷处理逻辑
                String dossierNum=realDossierNum+"";
                int genDossierNum = Integer.parseInt(at.getGenDossierNum());
                int genItemNum = Integer.parseInt(at.getGenItemNum());
                if (dossierNum.length()<genDossierNum){
                    int s=genDossierNum-dossierNum.length();
                    for (int i=0;i<s;i++){
                        dossierNum="0"+dossierNum;
                    }
                    doc.setDossierNum(dossierNum);
                }else{
                    doc.setDossierNum(dossierNum);
                }
                //处理卷下的件
                QueryWrapper<ArchivesDoc> updateWrapper=new QueryWrapper<>();
                updateWrapper.eq("dossierId",doc.getId());
                updateWrapper.eq("fileType","doc");
                List<ArchivesDoc> ArchivesDocs= archivesDocMapper.selectList(updateWrapper);
                int num=1;

                for (ArchivesDoc doc1:ArchivesDocs){
                    String itemNum=num+"";
                    for (int i=0;i<genItemNum-1;i++){
                        itemNum="0"+itemNum;
                    }
                    doc1.setItemNum(itemNum);
                    doc1.setFondsId(fondsId);
                    archivesDocMapper.updateById(doc1);
                    num++;
                }

            }

            //构造档案号
            if(archivesClass==null || StringUtils.isEmpty(archivesClass.getTreeStr())){
                doc.setClassNum(at.getTypeNum());
            }else{
                doc.setClassNum(at.getTypeNum()+"·"+archivesClass.getTreeStr());
            }
            if(StringUtils.isNotEmpty(fondsId)){
                ArchivesFonds archivesFonds = archivesFondsMapper.selectById(fondsId);
                doc.setFondsNum(archivesFonds.getFondsNum());
            }
            System.out.println("===========================1==============="+doc.getArchivalNum());
            //2024-6-17 构造档案号  不确定
//            Result<String> r = buildArchivalNum(doc, at, false);
//            if (r.getCode().equals(ResultCode.RESULT_ERROR.getCode())) return r;
            System.out.println("===========================1==============="+doc.getArchivalNum());
            doc.setFondsId(fondsId);
            archivesDocMapper.updateById(doc);

        }

        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", null);
    }




    @Override
    public Result<String> buildArchivalNum(ArchivesDoc archivesDoc, ArchivesType archivesType, boolean sole) {

        //当为1的时候，表示开启自动生成档号
        if("1".equals(archivesType.getAutoArchivalNum())){
            String classNum =  StringUtil.split(archivesDoc.getClassNum());
            archivesDoc.setClassNum(classNum);
            Map parseObject = JSON.parseObject(JSON.toJSONString(archivesDoc), Map.class);
            //修改根据genArchivalNum
            String genArchivalNum = fondsListService.genArchivalNum(archivesType.getGenArchivalNum(), archivesType.getGenType(), parseObject);
//            System.out.println("================="+archivesType.getGenArchivalNum());
//            System.out.println("================="+archivesType.getGenType());
//            System.out.println("=================123"+parseObject);
            if (StringUtils.isEmpty(genArchivalNum))
                return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "档号拼接列不能为空，请检查类目生成规则！！！", null);
            archivesDoc.setArchivalNum(genArchivalNum);
            //案件的档号和卷号要与，案卷的同步

            if (archivesDoc.getDossierId()!=null&&archivesDoc.getDossierId()==0&&"dossier".equals(archivesDoc.getFileType())){
                QueryWrapper<ArchivesDoc> updateWrapper=new QueryWrapper<>();
                updateWrapper.eq("dossierId",archivesDoc.getId());
                updateWrapper.eq("fileType","doc");
                ArchivesDoc doc=new ArchivesDoc();
                doc.setArchivalNum(archivesDoc.getArchivalNum());
                doc.setDossierNum(archivesDoc.getDossierNum());
                archivesDocMapper.update(doc,updateWrapper);
            }
        }

//        if (StringUtils.isEmpty(archivesDoc.getArchivalNum())) {
//            Map parseObject = JSON.parseObject(JSON.toJSONString(archivesDoc), Map.class);
//            String genArchivalNum = fondsListService.genArchivalNum(archivesType.getGenArchivalNum(), archivesType.getGenType(), parseObject);
//            if (StringUtils.isEmpty(genArchivalNum))
//                return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "档号拼接列不能为空，请检查类目生成规则！！！", null);
//            archivesDoc.setArchivalNum(genArchivalNum);
//        } else {
//            archivesDoc.setArchivalNum(archivesDoc.getArchivalNum());
//        }
        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", null);
    }

    @Override
    public ArchivesDoc builArchivesDocOut(ArchivesDoc doc) {
        if (!StringUtils.isEmpty(doc.getStoragePeriod())) {
            QueryWrapper<Dic> queryWrapper = new QueryWrapper<Dic>();
            queryWrapper.eq("dicType", "storagePeriod");
            queryWrapper.eq("dicCode", doc.getStoragePeriod());
            Dic dic = dicMapper.selectOne(queryWrapper);
            if (null != dic) doc.setStoragePeriod(dic.getDicValue());

        }
        return doc;
    }

    @Override
    public QueryWrapper<ArchivesDoc> builQueryWrapper(QueryWrapper<ArchivesDoc> queryWrapper, Classifys c) {

        //增加数据权限条件
        if (BaseUtil.listIsNotNullElement(c.getFonds())) queryWrapper.in("fondsId", c.getFonds());
        if (BaseUtil.listIsNotNullElement(c.getCategoryIds())) queryWrapper.in("classNum", c.getCategoryIds());
        if (BaseUtil.listIsNotNullElement(c.getClassIds())) queryWrapper.in("typeNum", c.getClassIds());
        if (BaseUtil.listIsNotNullElement(c.getFieldYearIds())) queryWrapper.in("archivalYear", c.getFieldYearIds());

        return queryWrapper;

    }


    @Async("cloudExecutor")
    @Override
    public void addCount(String fondsId, String type, String pattern, String year) {

        QueryWrapper<ArchivesStatistics> queryWrapper = new QueryWrapper<ArchivesStatistics>();
        queryWrapper.eq("year", year);
        //queryWrapper.eq("fondsId", fondsId);
        queryWrapper.eq("fonds", fondsId);
        queryWrapper.eq("type", type);
        ArchivesStatistics as = archivesStatisticsMapper.selectOne(queryWrapper);

        int i = 0;
        if (null != as) {
            buildNumber(pattern, as);
            i = archivesStatisticsMapper.updateById(as);
        } else {
            as = new ArchivesStatistics();
            //as.setFondsId(fondsId);
            as.setFonds(fondsId);
            as.setType(type);
            as.setYear(Integer.parseInt(year));
            as.setFlag("searching");
            as.setDocNum(0l);
            as.setDossierNum(0l);
            buildNumber(pattern, as);
            i = archivesStatisticsMapper.insert(as);

        }
        if (i < 1) {
            log.error(String.format("增加档案统计失败,全宗ID：%s、门类ID：%s、年度：%s、模式：%s", fondsId, type, year, pattern));

        }

    }


    //构造统计数量
    private void buildNumber(String pattern, ArchivesStatistics as) {
        if (StringUtils.isNotEmpty(pattern) && pattern.equals(DicDocPattern.PATTERN_1.getKey())) {
            as.setDossierNum(as.getDossierNum() == null ? 1l : as.getDossierNum() + 1l);
        }
        if (StringUtils.isNotEmpty(pattern) && pattern.equals(DicDocPattern.PATTERN_0.getKey())) {
            as.setDocNum(as.getDocNum() == null ? 1l : as.getDocNum() + 1l);
        }

    }


    @Override
    public boolean verifyDocNum(ArchivesDoc adBean) {

        //件号  卷号   没有不校验重复
        if (adBean.getFileType().equals(DicDocFileType.DOSSIER.getKey()) && StringUtils.isEmpty(adBean.getDossierNum())) {
            return true;
        } else {
            if (StringUtils.isEmpty(adBean.getItemNum())) return true;
        }

        QueryWrapper<ArchivesDoc> queryWrapper = ArchivesUtil.verifyRepetition(adBean);
        int i = archivesDocMapper.selectCount(queryWrapper);
        if (i > 0) return false;
        return true;

    }

    @Override
    public boolean verifyDocNumNew(ArchivesDoc adBean,List<String> ids) {

        //件号  卷号   没有不校验重复
        if (adBean.getFileType().equals(DicDocFileType.DOSSIER.getKey()) && StringUtils.isEmpty(adBean.getDossierNum())) {
            return true;
        } else {
            if (StringUtils.isEmpty(adBean.getItemNum())) return true;
        }

        QueryWrapper<ArchivesDoc> queryWrapper = ArchivesUtil.verifyRepetition(adBean);
        queryWrapper.notIn(ids!=null&&ids.size()>0,"id",ids);
        int i = archivesDocMapper.selectCount(queryWrapper);
        if (i > 0) return false;
        return true;

    }


    @Override
    public boolean verifyDDDoc(ArchivesDoc adBean) {

        QueryWrapper<ArchivesDoc> queryWrapper = ArchivesUtil.verifyRepetition(adBean);
        int i = archivesDocMapper.selectCount(queryWrapper);
        if (i > 0) return false;
        return true;

    }

    @Override
    public boolean verifyDDoc(ArchivesDoc adBean) {
        QueryWrapper<ArchivesDoc> queryWrapper = ArchivesUtil.verifyRepetition(adBean);
        int i = archivesDocMapper.selectCount(queryWrapper);
        if (i > 0) return false;
        return true;

    }

    /**
     * @description: 规则匹配   组卷
     * @author: lig
     * @date: 2021-09-15
     */
    @Override
    public boolean matchingConstitute(ArchivesDoc dossier, ArchivesDoc doc, ArchivesType at) {

        //2021-08-04 规则：档号、全宗号、目录号（系统字段为类目号）、案卷号、件号不重复
        QueryWrapper<ArchivesDoc> queryWrapper = new QueryWrapper<ArchivesDoc>();

        Map dossierMap = JSON.parseObject(JSON.toJSONString(dossier), Map.class);

        Map docObject = JSON.parseObject(JSON.toJSONString(doc), Map.class);
        List<GenCategoryNum> column = ArchivesUtil.genCategoryList(at.getConstituteRule(), at.getConstituteRuleSymbol(), docObject);

        List<Boolean> booleanList=new ArrayList<>();


        for (GenCategoryNum gcn : column) {
            if (StringUtils.isEmpty(gcn.getValue()) || !dossierMap.get(gcn.getColumn()).equals(gcn.getValue())) {
                //return false;
                continue;
            }else{
                booleanList.add(true);
            }
        }

        if(booleanList.size() !=0 && column!=null  && booleanList.size()==column.size()){
            return true;
        }else{
            return false;
        }

    }


    /**
     * @description: 校验案卷号重复
     * @author: lig
     * @date: 2021/8/5
     */
    @Override
    public boolean verifyDossierNum(ArchivesDoc adBean) {
        QueryWrapper<ArchivesDoc> queryWrapper = ArchivesUtil.verifyRepetition(adBean);
        int i = archivesDocMapper.selectCount(queryWrapper);
        if (i > 0) return false;
        return true;

    }

    /**
     * @description: 校验案卷号重复，升级改造版
     *
     * @author: lig
     * @date: 2022/9/15
     */
    @Override
    public boolean verifyDossierNumNew(ArchivesDoc adBean,List<String> ids) {
        QueryWrapper<ArchivesDoc> queryWrapper = ArchivesUtil.verifyRepetition(adBean);
        queryWrapper.notIn(ids!=null&&ids.size()>0,"id",ids);
        int i = archivesDocMapper.selectCount(queryWrapper);
        if (i > 0) return false;
        return true;

    }

    @Override
    public boolean verifyClassNumRepetition(ArchivesClass archivesClass) {
        QueryWrapper<ArchivesClass> qw = ArchivesUtil.builBaseQueryWrapper(new BaseQueryDto(archivesClass.getFondsId(),archivesClass.getTypeId()));
        if(null != archivesClass.getId())qw.notIn("id",archivesClass.getId());
        qw.eq("parentId",archivesClass.getParentId());
        qw.eq("classNum",archivesClass.getClassNum());

        int i = archivesClassMapper.selectCount(qw);
        if(i > 0 ) return true;
        return false;
    }

    @Override
    public QueryWrapper<ArchivesDoc> verifyRepetitionQueryWrapper(ArchivesDoc adBean) {
        return null;
    }

    @Override
    public boolean existArchive(ArchivesDoc doc) {
        boolean boo = false;
        QueryWrapper<ArchivesDoc> queryWrapperCF = ArchivesUtil.verifyRepetition(doc);

        if (archivesDocMapper.selectCount(queryWrapperCF) > 0) boo = true;
        return boo;

    }

    @Override
    public String buildClassNum(String fondsId, String typeId, String classNum) {
        String str = classNum;
        QueryWrapper<ArchivesClass> queryWrapper = new QueryWrapper<ArchivesClass>();
        queryWrapper.eq("fondsId", fondsId);
        queryWrapper.eq("typeId", typeId);
        queryWrapper.eq("classNum", classNum);

        ArchivesClass ac = archivesClassMapper.selectOne(queryWrapper);
        return ac.getTreeStr();

//        List<ArchivesClass> list = archivesClassMapper.selectList(queryWrapper);
//
//        if (BaseUtil.listIsNotNullElement(list)) {
//            Long parentId = list.get(0).getParentId();
//            if (null == parentId || parentId == 0) return str;
//
//            while (null != parentId && parentId > 0) {
//                ArchivesClass ac = archivesClassMapper.selectById(parentId);
//                if (null != ac) {
//                    str = ac.getClassNum() + "/" + str;
//                    parentId = ac.getParentId();
//                }
//
//            }
//
//
//        }
//        return str;

    }

    @Override
    public Map<String, Map<String, String>> buildDic() {
        Map<String, Map<String, String>> dic = new HashMap<>();
        dic.put("storagePeriod", new HashMap<String, String>());
        dic.put("openState", new HashMap<String, String>());

        // add by dm @date:2021-05-20	密级解析
        dic.put("secret", new HashMap<String, String>());
        // add end

        QueryWrapper<Dic> queryWrapperStoragePeriod = new QueryWrapper<Dic>();
        queryWrapperStoragePeriod.eq("dicType", "storagePeriod");
        List<Dic> storagePeriodList = dicMapper.selectList(queryWrapperStoragePeriod);
        QueryWrapper<Dic> queryWrapperOpenState = new QueryWrapper<Dic>();
        queryWrapperOpenState.eq("dicType", "openState");

        // modified by dm @date:2021-05-20	解决控制状态导入解析失败bug
        //List<Dic> openStateList = dicMapper.selectList(queryWrapperStoragePeriod);
        List<Dic> openStateList = dicMapper.selectList(queryWrapperOpenState);
        // modified end

        if (storagePeriodList != null && storagePeriodList.size() > 0) {
            for (Dic dicTemp : storagePeriodList) {
                Map<String, String> map = dic.get("storagePeriod");
                map.put(dicTemp.getDicValue(), dicTemp.getDicCode());
            }
        }
        if (openStateList != null && openStateList.size() > 0) {
            for (Dic dicTemp : openStateList) {
                Map<String, String> map = dic.get("openState");
                map.put(dicTemp.getDicValue(), dicTemp.getDicCode());
            }
        }

        // add by dm @date:2021-05-20	密级解析
        QueryWrapper<Dic> queryWrapperSecretPeriod = new QueryWrapper<Dic>();
        queryWrapperSecretPeriod.eq("dicType", "secret");
        List<Dic> secretList = dicMapper.selectList(queryWrapperSecretPeriod);
        if (secretList != null && secretList.size() > 0) {
            for (Dic dicTemp : secretList) {
                Map<String, String> map = dic.get("secret");
                map.put(dicTemp.getDicValue(), dicTemp.getDicCode());
            }
        }
        return dic;
    }

    @Override
    public Map<String, Map<String, String>> buildBaseDic() {
        Map<String, Map<String, String>> dic = new HashMap<>();
        dic.put("storagePeriod", new HashMap<String, String>());
        dic.put("openState", new HashMap<String, String>());

        // add by dm @date:2021-05-20	密级解析
        dic.put("secret", new HashMap<String, String>());
        // add end

        QueryWrapper<Dic> queryWrapperStoragePeriod = new QueryWrapper<Dic>();
        queryWrapperStoragePeriod.eq("dicType", "storagePeriod");
        List<Dic> storagePeriodList = dicMapper.selectList(queryWrapperStoragePeriod);
        QueryWrapper<Dic> queryWrapperOpenState = new QueryWrapper<Dic>();
        queryWrapperOpenState.eq("dicType", "openState");

        // modified by dm @date:2021-05-20	解决控制状态导入解析失败bug
        //List<Dic> openStateList = dicMapper.selectList(queryWrapperStoragePeriod);
        List<Dic> openStateList = dicMapper.selectList(queryWrapperOpenState);
        // modified end

        if (storagePeriodList != null && storagePeriodList.size() > 0) {
            for (Dic dicTemp : storagePeriodList) {
                Map<String, String> map = dic.get("storagePeriod");
                map.put(dicTemp.getDicCode(), dicTemp.getDicValue());
            }
        }
        if (openStateList != null && openStateList.size() > 0) {
            for (Dic dicTemp : openStateList) {
                Map<String, String> map = dic.get("openState");
                map.put(dicTemp.getDicCode(), dicTemp.getDicValue());
            }
        }

        // add by dm @date:2021-05-20	密级解析
        QueryWrapper<Dic> queryWrapperSecretPeriod = new QueryWrapper<Dic>();
        queryWrapperSecretPeriod.eq("dicType", "secret");
        List<Dic> secretList = dicMapper.selectList(queryWrapperSecretPeriod);
        if (secretList != null && secretList.size() > 0) {
            for (Dic dicTemp : secretList) {
                Map<String, String> map = dic.get("secret");
                map.put(dicTemp.getDicCode(), dicTemp.getDicValue());
            }
        }
        return dic;
    }

    @Override
    public Result<String> importArchives(ExportParam exportParam) {
        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);
        Map<String, Map<String, String>> dic = buildDic();

        String fondsId = exportParam.getFondsId();
        String typeId = exportParam.getTypeId();
        List<String> columns = exportParam.getColumns();
        String model = exportParam.getModel();

//        String url = exportParam.getUrl();
        String url = Base64Decoder.decodeStr(exportParam.getUrl(), Charset.forName("UTF-8"));


        if (StringUtils.isEmpty(url)) return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "请先上传要导入的文件！！！", null);
        int indexOf = url.indexOf("/");

        String dossierId = "0";
        String extType = "";
        if ("0".equals(model)) {
            extType = "doc";
            dossierId = StringUtils.isEmpty(exportParam.getDossierId()) ? "1" : exportParam.getDossierId();
        } else if ("1".equals(model)) {
            extType = "dossier";
            dossierId = "0";
        } else if ("2".equals(model)) {
            extType = "scattered";
            dossierId = "0";
        } else {
            return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "参数错误！！！", null);
        }

        List<ArchivesDoc> excelList = FileBaseUtil.parseArchivesExcel(ossDir + url, columns);
        List<ArchivesDoc> saveList = new ArrayList<>();
        for (ArchivesDoc aDoc : excelList) {
            ArchivesDoc archivesDoc = new ArchivesDoc();
            BeanUtils.copyProperties(aDoc, archivesDoc);
            archivesDoc.setStoragePeriod(dic.get("storagePeriod").get(aDoc.getStoragePeriod()));
            archivesDoc.setOpenState(dic.get("openState").get(aDoc.getOpenState()));
            archivesDoc.setSecret(dic.get("secret").get(aDoc.getSecret()));
            archivesDoc.setFondsId(fondsId);

            //classNum
            if (StringUtils.isNotEmpty(aDoc.getClassNum())) {
                if (RedisUtil.isAppoint(VersionsMarkType.VERSIONS_2)) {
                    if (!StringUtils.isEmpty(aDoc.getClassNum())) {
                        //指定版本去掉第一位  lig 2021-06-22
                        archivesDoc.setClassNum(aDoc.getClassNum().substring(1));
                    }
                } else if (RedisUtil.isAppoint(VersionsMarkType.VERSIONS_3)) {
                    //通过最后一位分类号拼接成系统格式
                    String strClassNum = buildClassNum(fondsId, typeId, aDoc.getClassNum());
                    archivesDoc.setClassNum(strClassNum);
                }
                //解析分类树
                parseClassNum(archivesDoc);
            }
            archivesDoc.setDocFrom(DicDocFrom.FROM_3.getKey());
            archivesDoc.setFileType(extType);
            archivesDoc.setState(exportParam.getState());
            archivesDoc.setDossierId(Long.parseLong(dossierId));

            if (StringUtils.isNotEmpty(typeId)) archivesDoc.setTypeId(Long.parseLong(typeId));
            archivesDoc.setDocFrom("3");


            if ("1".equals(exportParam.getModel()) && !verifyDossierNum(archivesDoc))
                return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "卷号" + archivesDoc.getDossierNum() + "重复！！！", null);
            if ("0".equals(exportParam.getModel()) && !verifyDDoc(archivesDoc))
                return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "件号" + archivesDoc.getItemNum() + "重复！！！", null);
            if (StringUtils.isEmpty(archivesDoc.getSecret())) ArchivesDoc.initData(archivesDoc);

            archivesDocMapper.insert(archivesDoc);
//            saveList.add(archivesDoc);

        }

//        docService.saveBatch(saveList);

        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", null);
    }


    @Override
    public String buildFileName(File tempFile, ArchivesDoc doc, String pattern) {
//        String newName = FileBaseUtil.getFileDirName(tempFile);
        String newName = tempFile.getName();
        //目录默认追加.pdf
        if (newName.lastIndexOf(".") < 1) newName = newName + ".pdf";
        String ext = "." + FileBaseUtil.getFileNameExt(newName);

        if (DicDocPattern.PATTERN_0.getKey().equals(pattern)) {
            newName = doc.getItemNum() + ext;
        }

        //版本标识 lig  2021-06-10
        if (RedisUtil.isAppoint(VersionsMarkType.VERSIONS_2)) {

            String unitsName = "";

            //unitsName = doc.getTypeNum();

            long typeId=doc.getTypeId();
            long classId= doc.getClassId();
            ArchivesType archivesType= archivesTypeMapper.selectById(typeId);
            ArchivesClass ArchivesClass = archivesClassMapper.selectById(classId);
            String treeStr=ArchivesClass.getTreeStr().replace("·","");
            unitsName=archivesType.getTypeNum()+treeStr;

            //图片转pdf的文件名按照指定格式《单位名称-年度-月份-件号（凭证号）》
            newName = ArchivesUtil.builImgToPdfFileName(doc, unitsName) + ext;
        }
        return newName;
    }

    @Override
    public void parseClassNum(ArchivesDoc doc) {

//        //密级默认0 开放状态
//        if(StringUtils.isEmpty(archivesDossier.getSecret()))archivesDossier.setSecret("0");

        String classIdStr = doc.getClassNum();//  分类号/分类号/分类号


        Long classId = null;
        if (!StringUtils.isEmpty(classIdStr)) {
            String[] classArr = classIdStr.split("·");
            if (classArr.length > 0) {

                //第一级为门类  获取门类号
                ArchivesType at = archivesTypeMapper.selectOne(new QueryWrapper<ArchivesType>().eq("fondsId", doc.getFondsId()).eq("typeNum", classArr[0]));
                if (null == at) throw new BaseException(ResultCode.RESULT_ERROR.getCode(), "没有找到对应的门类");
                doc.setTypeId(at.getId());

                QueryWrapper qw = new QueryWrapper();
                qw.eq("fondsId", doc.getFondsId());
                qw.eq("typeId", at.getId());
                qw.eq("classNum", classArr[1]);
                qw.eq("parentId", 0);

                ArchivesClass tempAc = archivesClassMapper.selectOne(qw);
                if (null == tempAc) throw new BaseException(ResultCode.RESULT_ERROR.getCode(), "没有找到对应的分类");
                classId = tempAc.getId();

                for (int i = 2; i < classArr.length; i++) {
                    QueryWrapper<ArchivesClass> qw2 = new QueryWrapper();
                    qw2.eq("fondsId", doc.getFondsId());
                    qw2.eq("typeId", doc.getTypeId());
                    qw2.eq("classNum", classArr[i]);
                    qw2.eq("parentId", classId);

                    ArchivesClass tempAc2 = archivesClassMapper.selectOne(qw2);
                    //ArchivesClass tempAc2 = archivesClassMapper.selectById(qw2);
                    if (null == tempAc2) throw new BaseException(ResultCode.RESULT_ERROR.getCode(), "没有找到对应的子分类");
//                    QueryWrapper<ArchivesClass> qw2 = new QueryWrapper();
//                    qw2.eq("fondsId", archivesDossier.getFondsId());
//                    qw2.eq("typeId", archivesDossier.getTypeId());
//                    qw2.eq("classId", classArr[i]);
//                    qw2.eq("parentId", classId);
//
//                    ArchivesClass tempAc2 = archivesClassMapper.selectOne(qw2);
                    if (null != tempAc2) classId = tempAc2.getId();
                }

            }

            doc.setClassId(classId);
//            classIdStr = classIdStr.substring(classIdStr.indexOf("·") + 1);
//            doc.setClassNum(classIdStr);
        }


    }

    @Override
    public List<ArchivesDoc> gainDocById(String docId) {
        List<ArchivesDoc> list = new ArrayList();
        ArchivesDoc doc = archivesDocMapper.selectById(docId);
        if (doc.getFileType().equals(DicDocFileType.DOSSIER.getKey())) {
            list = archivesDocMapper.selectList(new QueryWrapper<ArchivesDoc>().eq("dossierId", docId).eq("fileType", DicDocFileType.DOC));
        }
        return list;
    }

    @Async("cloudExecutor")
    @Override
    public void addArticle(List<String> ids) {

        String tempPath = RedisUtil.getSysConfig(SystemConfigType.TEMP_PATH);

        List<ArchivesDoc> srcDocList = archivesDocMapper.selectBatchIds(ids);
        List<ArchivesDoc> docList = gainDocList(srcDocList);


        System.err.println("检索库ID：" + Joiner.on(",").join(ids));
        articleMapper.deleteBatchIds(ids);

        docList.forEach((ArchivesDoc doc) -> {
            Article article = new Article();
            article.setId(doc.getId());
            article.setTitle(doc.getTitle());
            article.setArchivalNum(doc.getArchivalNum());
            article.setDutyPeople(doc.getDutyPeople());

            List<ArchivesDocFile> docFileList = archivesDocFileMapper.selectList(new QueryWrapper<ArchivesDocFile>().eq("docId", doc.getId()));
            if (BaseUtil.listIsNotNullElement(docFileList)) {
//                article.setFileName(Joiner.on(",").join(docFileList));
                StringBuffer fileNames = new StringBuffer();
                docFileList.forEach((ArchivesDocFile adFile) -> {
                    fileNames.append(adFile.getFileName());
                    if (adFile.getExtName().equals(FileExt.pdf.getDesc())) {
                        //获取文件
                        File downFile = uploadService.gainFile(adFile.getFileUrl());
                        if(downFile!=null){
                            //解析
                            Map<String, Object> m = PdfUtils.gainPdfContent(downFile.getAbsolutePath(), tempPath);
                            StringBuffer sb = new StringBuffer();
                            String text = m.get("text").toString().trim();
                            text = text.replaceAll("\r", "");
                            text = text.replaceAll("\n", "");
                            sb.append(text);

//                        //ocr
//                        Map imgs = (Map) m.get("imgs");
//                        imgs.forEach((k, v) -> sb.append(OcrUtil.ocrImage(v.toString())) );

                            article.setContent(sb.toString());
                        }
                    }
                });
                article.setFileName(fileNames.toString());
            }
            articleMapper.insert(article);

        });

    }

    @Override
    public List<ArchivesDoc> gainDocList(List<ArchivesDoc> srcDocList) {
        List<ArchivesDoc> docList = new ArrayList<>();
        srcDocList.forEach((ArchivesDoc doc) -> {
            if (doc.getFileType().equals(DicDocFileType.DOSSIER.getKey())) {
                List<ArchivesDoc> docListByDossier = archivesDocMapper.selectList(new QueryWrapper<ArchivesDoc>().eq("dossierId", doc.getDossierId()));
                docList.addAll(docListByDossier);
            } else {
                docList.add(doc);
            }

        });

        return docList;
    }

    @Override
    public QueryWrapper<ArchivesDoc> buildStatisticsQueryWrapper(QueryWrapper<ArchivesDoc> queryWrapperDoc, ArchivesStatisticsParamDto paramDto) {
        if (null == queryWrapperDoc) queryWrapperDoc = new QueryWrapper<ArchivesDoc>();
        if (StringUtils.isNotEmpty(paramDto.getIsDelete())) {
            queryWrapperDoc.eq("isDelete", paramDto.getIsDelete());
        }
        if (StringUtils.isNotEmpty(paramDto.getState())) {
            queryWrapperDoc.eq("state", paramDto.getState());
        }
        if (StringUtils.isNotEmpty(paramDto.getFileType())) {
            queryWrapperDoc.eq("fileType", paramDto.getFileType());
        }
        if (StringUtils.isNotEmpty(paramDto.getFondsId())) {
            queryWrapperDoc.eq("fondsId", paramDto.getFondsId());
        }
        if (StringUtils.isNotEmpty(paramDto.getTypeNum())) {
            queryWrapperDoc.eq("typeId", paramDto.getTypeId());
        }
        if (StringUtils.isNotEmpty(paramDto.getYear())) {
            queryWrapperDoc.between("archivalYear", paramDto.getYearStart(), paramDto.getYearEnd());
        }
        if (StringUtils.isNotEmpty(paramDto.getFilingStartDate()) && StringUtils.isNotEmpty(paramDto.getFilingEndDate())) {
            queryWrapperDoc.between("sysArchivingTime", paramDto.getFilingStartDate(), paramDto.getFilingEndDate());
        } else if (StringUtils.isNotEmpty(paramDto.getFilingStartDate())) {
            queryWrapperDoc.ge("sysArchivingTime", paramDto.getFilingStartDate());
        }
        return queryWrapperDoc;

    }

    @Override
    public List<ArchivesDoc> gainStatisticsType(ArchivesStatisticsParamDto paramDto) {
        /*Map map = new LinkedHashMap();
        QueryWrapper<ArchivesType> typeQw = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(paramDto.getFondsId())) typeQw.eq("fondsId", paramDto.getFondsId());
        if (StringUtils.isNotEmpty(paramDto.getTypeId())) typeQw.eq("id", paramDto.getTypeId());
//        typeQw.groupBy("typeId");
        typeQw.orderByAsc("sort");
        List<ArchivesType> typeList = archivesTypeMapper.selectList(typeQw);*/

        /*for (ArchivesType at : typeList) {
            QueryWrapper<ArchivesDoc> qw = buildStatisticsQueryWrapper(null, paramDto);
            qw.eq("state", DicDocState.archive.getKey());
            qw.eq("isDelete", BaseConstants.DELETE_NORMAL);
            if (at.getModel().equals(DicDocPattern.PATTERN_1)) {
                qw.eq("fileType", DicDocFileType.DOSSIER);
            }
            if (at.getModel().equals(DicDocPattern.PATTERN_0)) {
                qw.eq("fileType", DicDocFileType.DOC);
            }
            qw.isNull("typeId");
            qw.groupBy("typeId");
            //qw.eq("typeId", at.getId());
            int i = archivesDocMapper.selectCount(qw);
            map.put(at.getTypeName(), i);
        }*/
        QueryWrapper<ArchivesDoc> qw = buildStatisticsQueryWrapper(null, paramDto);
        qw.select("count(*) itemCount,typeId");
        qw.eq("state", DicDocState.archive.getKey());
        qw.eq("isDelete", BaseConstants.DELETE_NORMAL);
        if (StringUtils.isNotEmpty(paramDto.getFondsId())) qw.eq("fondsId", paramDto.getFondsId());
        if (StringUtils.isNotEmpty(paramDto.getTypeId())) qw.eq("id", paramDto.getTypeId());


        qw.isNotNull("typeId");
        qw.groupBy("typeId");
        //qw.eq("typeId", at.getId());
        List<ArchivesDoc> list= archivesDocMapper.selectList(qw);
        for(ArchivesDoc doc:list){
            ArchivesType type = archivesTypeMapper.selectById(doc.getTypeId());
            doc.setTypeName(type.getTypeName());
        }


        return list;
    }

    @Override
    public Integer statisticsFonds(String fondsId) {
        QueryWrapper<ArchivesFonds> qwFonds = new QueryWrapper<ArchivesFonds>();
        if (StringUtils.isNotEmpty(fondsId)) qwFonds.in("id", fondsId);
        Integer fondsCount = archivesFondsMapper.selectCount(qwFonds);
        return fondsCount != null ? fondsCount : 0;
    }

    @Override
    public Integer statisticsType(String fondsId, String typeId) {
        QueryWrapper<ArchivesType> qwType = new QueryWrapper<ArchivesType>();
        if (StringUtils.isNotEmpty(fondsId)) qwType.in("fondsId", fondsId);
        if (StringUtils.isNotEmpty(typeId)) qwType.in("id", typeId);
        Integer typeCount = archivesTypeMapper.selectCount(qwType);
        return typeCount != null ? typeCount : 0;
    }

    @Override
    public Integer statisticsArchives(ArchivesStatisticsParamDto paramDto) {
        QueryWrapper qw = buildStatisticsQueryWrapper(null, paramDto);
        Integer archivesCount = archivesDocMapper.selectCount(qw);
        return archivesCount != null ? archivesCount : 0;
    }

    @Override
    public Integer statisticsArchivesFrom(DicDocFrom dicDocFrom,DicDocFileType dicDocFileType,String fondsId,String typeId) {

        QueryWrapper<ArchivesDoc> fromQw1 = new QueryWrapper();
        fromQw1.eq("docFrom", dicDocFrom.getKey());
        fromQw1.eq("fileType",dicDocFileType.getKey());
        fromQw1.eq("isDelete","0");
        fromQw1.eq("state","2");
        fromQw1.eq(StringUtils.isNotEmpty(fondsId),"fondsId",fondsId);
        fromQw1.eq(StringUtils.isNotEmpty(typeId),"typeId",typeId);
        if(dicDocFileType.getKey().equals(DicDocFileType.DOC.getKey())){
            fromQw1.eq("dossierId","0");
        }
        int from1Count = archivesDocMapper.selectCount(fromQw1);
        return from1Count;

    }

    @Override
    public String gainDocFileList(Map<String, Object> filesParamFromDoc1) {

        List<ArchivesDocFile> fileList = archivesDocMapper.queryFilesSize(filesParamFromDoc1);


        double sum = fileList.stream().mapToDouble(ArchivesDocFile -> StringUtils.isNotEmpty(ArchivesDocFile.getFileSize()) ? Double.parseDouble(ArchivesDocFile.getFileSize()) : 0d).sum();

        String totalByteFromDoc1 = new DecimalFormat("###0.0#").format(sum);
        System.err.println("文件总大小：" + totalByteFromDoc1);
        BigDecimal bg111 = new BigDecimal(totalByteFromDoc1);
        BigDecimal bg222 = BigDecimal.valueOf(1073741824d);//1024/1024/1024
        BigDecimal divide = bg111.divide(bg222, 2, BigDecimal.ROUND_DOWN);
        return divide.toString();

    }

    @Override
    public List<ArchivesTypeDoc> gainBaseField(String fileType, String typeId) {
        QueryWrapper<ArchivesTypeDoc> col = new QueryWrapper<>();
        col.eq("extType", fileType);
        col.eq("isList", "1");
        col.eq("typeId", typeId);
        col.select("id", "extColumn", "columnComment", "colsize", "sort", "extType", "dataType", "listLength");
        List<ArchivesTypeDoc> baseCols = archivesTypeDocMapper.selectList(col);
        return baseCols;
    }

    @Override
    public List<String> gainBaseQueryField(String fileType, String typeId) {
        QueryWrapper<ArchivesTypeDoc> queryCol = new QueryWrapper<>();
        queryCol.eq("extType", fileType);
        queryCol.eq("isQuery", "1");
        queryCol.eq("typeId", typeId);
        queryCol.select("extColumn");
        queryCol.notIn("extColumn","typeNum","fondsNum","classNum");
        List<ArchivesTypeDoc> queryCols = archivesTypeDocMapper.selectList(queryCol);
        List<String> query = new ArrayList<>();
        for (int i = 0; i < queryCols.size(); i++) {
            query.add(queryCols.get(i).getExtColumn());
        }
        return query;
    }

    @Override
    public Result fourDetection(ArchivesDocReceive adr) {
        List<ArchivesTestingFour> atfList = archivesTestingFourMapper.selectList(new QueryWrapper<ArchivesTestingFour>().eq("source", "OA"));
        if (!BaseUtil.listIsNotNullElement(atfList)) return ResultUtil.error("请检查（四性检测）配置项");

        atfList.forEach((ArchivesTestingFour atf) -> {
            String optionList = atf.getOptionList();
            Map jsonObject = (Map) JSONObject.parse(optionList);

            if (null != jsonObject) {

                for (DicFourSexClassify dfsc : DicFourSexClassify.values()) {
                    Map m = (Map) jsonObject.get(dfsc.getKey());
                    if (null != m) detection(adr, m, dfsc, atf.getTestType());
                }

//                //真实性
//                if (atf.getTestType().equals(DicFourSex.TYPE_1.getKey())) {
//
//                    for (DicFourSexClassify dfsc : DicFourSexClassify.values()) {
//                        Map m = (Map) jsonObject.get(dfsc.getKey());
//                        if (null != m) detection(adr, m, dfsc);
//                    }
//
//
//                }
//                //完整性
//                if (atf.getTestType().equals(DicFourSex.TYPE_2.getKey())) {
//
//                    for (DicFourSexClassify dfsc : DicFourSexClassify.values()) {
//                        Map m = (Map) jsonObject.get(dfsc.getKey());
//                        if (null != m) detection(adr, m, dfsc);
//                    }
//
//
//                }


//                //准确性
////                m1.get(DicFourSexClassify.TYPE_1_1.getKey())
//                if (atf.getTestType().equals(DicFourSex.TYPE_1.getKey())) {
//                    //长度检测
//                    if (atf.getTestType().equals(DicFourSexClassify.TYPE_1_1.getKey())) {
////                        Map m1 = (Map) jsonObject.get(atf.getTestType());
//                        detectionLength(adr, (Map) jsonObject.get(atf.getTestType()));
//                    }
//                    //类型检测
//                    if (atf.getTestType().equals(DicFourSexClassify.TYPE_1_2.getKey())) {
//                        detectionType(adr, (Map) jsonObject.get(atf.getTestType()));
//                    }
//
//                }
            }


        });
        return ResultUtil.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteFile(List<ArchivesDocFile> list) {
        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);
        list.forEach((ArchivesDocFile docFile) -> {
            int i = archivesDocFileMapper.deleteById(docFile.getId());
            if (i > 0) {
                String ext = FileBaseUtil.getFileNameExt(docFile.getFileUrl());

                if (FileBaseUtil.isWord(ext)
                        || FileBaseUtil.isExcel(ext)) {
                    String pdfFile = FileBaseUtil.builFileAllName(FileBaseUtil.getFileNameFront(docFile.getFileUrl()), FileExt.pdf.getDesc());
                    FileUtil.del(new File(ossDir + pdfFile));
                }
                FileUtil.del(new File(ossDir + docFile.getFileUrl()));

                //存储模式
                String accType = RedisUtil.getSysConfig(SystemConfigType.ACCESSORY_TYPE);
                if (!org.springframework.util.StringUtils.isEmpty(accType)) {
                    if (accType.equals(AccessoryType.TYPE_2.getKey())) {
                        //删除桶里的数据
                        Result<String> rFile = uploadService.removeFile(docFile.getFileUrl());
                        if (rFile.getCode().equals(ResultCode.RESULT_SUCCESS.getCode())) {
                            System.out.println("删除存储数据（成功）：" + rFile.getData());
                        } else {
                            System.err.println("删除存储数据（失败）：" + rFile.getData());
                        }

                    }
                }


            }
        });
        return ResultUtil.success("删除成功！");


    }

    @Override
    public void buildBaseInfo(ArchivesDoc doc) {
        if(StringUtils.isNotEmpty(doc.getFondsId()))doc.setFondsNum(archivesFondsMapper.selectById(doc.getFondsId()).getFondsNum());
        if(null != doc.getTypeId())doc.setTypeNum(archivesTypeMapper.selectById(doc.getTypeId()).getTypeNum());
        if(null != doc.getClassId())doc.setClassNum(archivesClassMapper.selectById(doc.getClassId()).getClassNum());
        if("存在".equals(doc.getFondsName()))doc.setFondsName(archivesFondsMapper.selectById(doc.getFondsId()).getFondsName());
    }


//    @Override
//    public ArchivesClass parentClass(long classId) {
//        return archivesClassMapper.selectById(classId);
//    }


    private ArchivesClass getParent(Long parentId) {
        return archivesClassMapper.selectById(parentId);
    }


    /**
     * @description: 四性检测  检测长度
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionLength(ArchivesTestingFourRecord atfr, Object val, Object v) {
        atfr.setTest("false");
        try {
            if (val.toString().length() <= Integer.parseInt(v.toString())) {
                atfr.setTest("true");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * @description: 四性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detection(ArchivesDocReceive adr, Map testMap, DicFourSexClassify dic, String testType) {
        String classifyKey = dic.getKey();
        String classifyVal = dic.getValue();
        testMap.forEach((k, v) -> {

                    ArchivesTestingFourRecord atfr = new ArchivesTestingFourRecord();

                    ArchivesTestingFourMetadata atfm = archivesTestingFourMetadataMapper.selectById(k.toString());
                    Object receiveVal = null;
                    if (null != atfm) {
                        receiveVal = gainClassFieldVal(atfm.getField(), adr);
                        atfr.setField(atfm.getField());
                    }


                    //长度检测
                    if (dic == DicFourSexClassify.TYPE_1_1) {
                        detectionLength(atfr, receiveVal, v);
                    }
                    //类型检测
                    if (dic == DicFourSexClassify.TYPE_1_2) {
                        detectionType(atfr, receiveVal, v);
                    }
                    //合理性检测
                    if (dic == DicFourSexClassify.TYPE_1_3) {
                        detectionRationality(atfr, receiveVal, v);
                    }
                    //特殊字符检测
                    if (dic == DicFourSexClassify.TYPE_1_4) {
                        detectionSpecialStr(atfr, receiveVal, v);
                    }
                    if (dic == DicFourSexClassify.TYPE_1_5) {
                        detectionRepeatability(atfr, receiveVal, atfm.getField());
                    }

                    if (dic == DicFourSexClassify.TYPE_1_6) {
                        detectionContentAuthenticity(atfr, receiveVal, null != atfm ? atfm.getField() : "", adr);
                    }
                    if (dic == DicFourSexClassify.TYPE_1_7) {
                        detectionFileRelevance(atfr, adr);
                    }
                    if (dic == DicFourSexClassify.TYPE_1_8) {
                        detectionBaseStandard(atfr, adr);
                    }
                    if (dic == DicFourSexClassify.TYPE_1_9) {
                        atfr.setTest("true");
                    }
                    //@TODO 之后的需要补充
                    if (dic == DicFourSexClassify.TYPE_3_1) {
                        detectionContentAuthenticity(atfr, receiveVal, null != atfm ? atfm.getField() : "");
                    }
                    //@TODO 之后的需要补充
                    if (dic == DicFourSexClassify.TYPE_4_1) {
                        detectionContentAuthenticity(atfr, receiveVal, null != atfm ? atfm.getField() : "");
                    }


                    if (StringUtils.isEmpty(atfr.getTest())) return;

                    atfr.setDocId(adr.getDocId().toString());
                    atfr.setTestType(testType);
                    atfr.setTestClassify(classifyKey);
                    atfr.setCreateTime(LocalDateTime.now());
                    atfr.setSource(adr.getSource());

                    if (null != atfm) {
                        atfr.setDescribes(dic.getValue() + "，" + v.toString() + ":" + atfm.getName() + "," + (atfr.getTest().equals("true") ? "通过" : "不通过"));
                    } else {
                        atfr.setDescribes(dic.getValue() + "，" + (atfr.getTest().equals("true") ? "通过" : "不通过"));
                    }


                    archivesTestingFourRecordMapper.insert(atfr);


                }
        );

    }

    /**
     * @description: 四性检测  检测类型
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionType(ArchivesTestingFourRecord atfr, Object receiveVal, Object v) {


        try {
            if (v.toString().equals("字符型")) {
                receiveVal.toString();
            }
            if (v.toString().equals("数值型")) {
                Double.parseDouble(receiveVal.toString());
            }
            if (v.toString().equals("日期型") || v.toString().equals("日期时间性")) {
                Date d = new Date(receiveVal.toString());
            }
            atfr.setTest("true");
        } catch (Exception e) {
            e.printStackTrace();
            atfr.setTest("false");
        }

//        atfr.setDescribes(dic.getValue() + "，" + v.toString() + ":" + atfm.getName() + "," + (atfr.getTest().equals("true") ? "通过" : "不通过"));


    }

    /**
     * @description: 四性检测  合理性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionRationality(ArchivesTestingFourRecord atfr, Object receiveVal, Object rule) {

        String testResult = "false";
        try {
            String[] rules = rule.toString().split(",");
            long ruleStart = Long.parseLong(rules[0]);
            long ruleEnd = Long.parseLong(rules[1]);

            long rValLong = Long.parseLong(receiveVal.toString());

            if (rValLong >= ruleStart && rValLong <= ruleEnd) {
                testResult = "true";
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        atfr.setTest(testResult);


    }

    /**
     * @description: 四性检测  特殊字符检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionSpecialStr(ArchivesTestingFourRecord atfr, Object receiveVal, Object rule) {

        String testResult = "false";
        try {

            String[] rules = rule.toString().split("、");
            for (String ruleStr : rules) {
                if (receiveVal.toString().contains(ruleStr)) {
                    atfr.setTest(testResult);
                    return;
                }
                ;
            }

            testResult = "true";


        } catch (Exception e) {
            e.printStackTrace();
        }
        atfr.setTest(testResult);


    }

    /**
     * @description: 四性检测  重复性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionRepeatability(ArchivesTestingFourRecord atfr, Object receiveVal, String fieldName) {
        String testResult = "false";
        try {

            int i = archivesDocMapper.selectCount(new QueryWrapper<ArchivesDoc>().eq(fieldName, receiveVal));
            if (i <= 0) {
                testResult = "true";
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        atfr.setTest(testResult);


    }

    /**
     * @description: 四性检测  电子文件 内容真实性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionContentAuthenticity(ArchivesTestingFourRecord atfr, Object receiveVal, String fieldName, ArchivesDocReceive adr) {
        atfr.setTest("false");
        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);

        try {
            if (fieldName.equals("docTotalSize")) {
                List<AccessoryXml> accessoryList = adr.getAccessory();
                BigDecimal docTotalSize = new BigDecimal(0d);

                for (AccessoryXml accessory : accessoryList) {
                    File file = new File(ossDir + accessory.getFileUrl());
                    long fLength = file.length();
                    Double i = (fLength / (1024.0 * 1024.0));//MB
                    BigDecimal fileLength = new BigDecimal(i.toString());

//                fileLength = fileLength.add(fileLength);
                    docTotalSize = docTotalSize.add(fileLength.setScale(1, BigDecimal.ROUND_DOWN));
                }

                String receiveStr = receiveVal.toString().substring(0, receiveVal.toString().indexOf("MB"));
                BigDecimal receiveBig = new BigDecimal(receiveStr);
                System.err.println("附件总大小比较，实际文件大小：" + docTotalSize + "填写文件大小：" + receiveBig);
                int i = docTotalSize.compareTo(receiveBig);
                if (i == 0) atfr.setTest("true");

            }

            //总数量
            if (fieldName.equals("docCount")) {
                List<AccessoryXml> accessoryList = adr.getAccessory();
                if (BaseUtil.listIsNotNullElement(accessoryList) && accessoryList.size() == Integer.parseInt(receiveVal.toString())) {
                    atfr.setTest("true");
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    /**
     * @description: 四性检测  电子文件 元数据与内容关联一致性
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionFileRelevance(ArchivesTestingFourRecord atfr, ArchivesDocReceive adr) {
        atfr.setTest("false");
        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);

        try {

            List<AccessoryXml> accessoryList = adr.getAccessory();
            BigDecimal docTotalSize = new BigDecimal(0d);

            for (AccessoryXml accessory : accessoryList) {
                File file = new File(ossDir + accessory.getFileUrl());
                long fLength = file.length();
                Double i = (fLength / (1024.0 * 1024.0));//MB
                BigDecimal fileLength = new BigDecimal(i.toString());

                //                fileLength = fileLength.add(fileLength);
                docTotalSize = docTotalSize.add(fileLength.setScale(1, BigDecimal.ROUND_DOWN));
            }

            String receiveStr = adr.getDocTotalSize().substring(0, adr.getDocTotalSize().indexOf("MB"));
            BigDecimal receiveBig = new BigDecimal(receiveStr);
            System.err.println("附件总大小比较，实际文件大小：" + docTotalSize + "填写文件大小：" + receiveBig);
            int i = docTotalSize.compareTo(receiveBig);
            if (i == 0) {
                if (Integer.parseInt(adr.getDocCount()) == accessoryList.size()) {
                    atfr.setTest("true");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
    /**
     * @description: 四性检测  基本信息表规范性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionBaseStandard(ArchivesTestingFourRecord atfr, ArchivesDocReceive adr) {
        atfr.setTest("false");

        try {

            if(StringUtils.isEmpty(adr.getFilingId()))return ;
            if(StringUtils.isEmpty(adr.getFilingPageType()))return ;
            if(StringUtils.isEmpty(adr.getDocCount()))return ;
            if(StringUtils.isEmpty(adr.getDocTotalSize()))return ;
            if(StringUtils.isEmpty(adr.getBuildUnitName()))return ;
            if(StringUtils.isEmpty(adr.getDocNum()))return ;
            if(StringUtils.isEmpty(adr.getYear()))return ;
            if(StringUtils.isEmpty(adr.getTitle()))return ;
            if(StringUtils.isEmpty(adr.getLott()))return ;
            if(StringUtils.isEmpty(adr.getDate()))return ;
            if(StringUtils.isEmpty(adr.getPages()))return ;
            if(StringUtils.isEmpty(adr.getProcessState()))return ;
            if(StringUtils.isEmpty(adr.getArchivePerson()))return ;
            if(StringUtils.isEmpty(adr.getArchiveTime()))return ;
            if(StringUtils.isEmpty(adr.getArchiveDept()))return ;


            List<AccessoryXml> accessory = adr.getAccessory();
            accessory.forEach((AccessoryXml aXml)->{
                if(StringUtils.isEmpty(aXml.getFileName()))return ;
                if(StringUtils.isEmpty(aXml.getFileFormat()))return ;
                if(StringUtils.isEmpty(aXml.getFileSize()))return ;
            });

            List<StepXML> step = adr.getStep();
            step.forEach((StepXML sXml)->{
                if(StringUtils.isEmpty(sXml.getStepName()))return ;
                if(StringUtils.isEmpty(sXml.getOperator()))return ;
                if(StringUtils.isEmpty(sXml.getResultType()))return ;
                if(StringUtils.isEmpty(sXml.getOpinions()))return ;
                if(StringUtils.isEmpty(sXml.getOperTime()))return ;
            });


        } catch (Exception e) {
            e.printStackTrace();
            atfr.setTest("false");
        }

        atfr.setTest("true");


    }


    /**
     * @description: 四性检测  电子文件 内容真实性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionContentAuthenticity(ArchivesTestingFourRecord atfr, Object receiveVal, String fieldName) {
        atfr.setTest("true");


    }


    /**
     * @description: 获取class里的属性值
     * @author: lig
     * @date: 2022/2/25
     */
    private Object gainClassFieldVal(String field, Object adr) {
        Object receiveVal = null;
        try {
            // 得到类对象
            Class userCla = (Class) adr.getClass();
            Field fs = userCla.getDeclaredField(field);
            fs.setAccessible(true); // 设置些属性是可以访问的
            receiveVal = fs.get(adr);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        //System.out.println("val：" + receiveVal);
        return receiveVal;

    }

    /**
     * 构件持久化文件保存路径
     * @param fondsId
     * @param typeId
     * @param classId
     * @param dossierNum
     * @param docNum
     * @return
     */
    private StringBuilder builderDurableUrl(String fondsId,String typeId,String classId,String dossierNum,String docNum){
        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);
        StringBuilder stringBuilder=new StringBuilder(ossDir);
        stringBuilder.append("durable/")
                .append(fondsId)
                .append("/")
                .append(typeId)
                .append("/")
                .append(classId)
                .append("/")
                .append(dossierNum);
                if(!StringUtils.isEmpty(docNum)){
                    stringBuilder.append("/")
                            .append(docNum);
                }
        return stringBuilder;
    }

//    /**
//     * @description: 四性检测  检测类型
//     * @author: lig
//     * @date: 2022/2/24
//     */
//    private void detectionType(ArchivesDocReceive adr, Map testMap) {
//
//        String classifyKey = DicFourSexClassify.TYPE_1_2.getKey();
//        String classifyVal = DicFourSexClassify.TYPE_1_2.getValue();
//
//        testMap.forEach((k, v) -> {
//                    ArchivesTestingFourMetadata atfm = archivesTestingFourMetadataMapper.selectById(k.toString());
//                        // 得到类对象
//                        Class userCla = (Class) adr.getClass();
//                    Object val = null;
//                    try {
//                        Field fs = userCla.getDeclaredField(atfm.getField());
//                        fs.setAccessible(true); // 设置些属性是可以访问的
//                        val = fs.get(adr);
//                        System.out.println("val：" + val);
//                    } catch (NoSuchFieldException | IllegalAccessException e) {
//                        e.printStackTrace();
//                    }
//                    ArchivesTestingFourRecord atfr = new ArchivesTestingFourRecord();
//
//                    try {
//                        if (v.toString().equals("字符型")) {
//                            val.toString();
//                        }
//                        if (v.toString().equals("数值型")) {
//                            Double.parseDouble(val.toString());
//                        }
//                        if (v.toString().equals("日期型") || v.toString().equals("日期时间性")) {
//                            Date d = new Date(val.toString());
//                        }
//                        atfr.setTest("true");
//                    } catch (Exception e) {
//                        atfr.setTest("false");
//                    }
//
//                    atfr.setDescribes(classifyVal + "，"+v.toString()+":"+atfm.getName()+"," + (atfr.getTest().equals("true")?"通过":"不通过"));
//
//
//                    atfr.setDocId(adr.getDocId().toString());
//                    atfr.setTestType(DicFourSex.TYPE_1.getKey());
//                    atfr.setTestClassify(classifyKey);
//                    atfr.setField(atfm.getField());
//                    atfr.setCreateTime(LocalDateTime.now());
//
//
//                    archivesTestingFourRecordMapper.insert(atfr);
//
//                    // 得到此属性的值
//
//
//                }
////                                System.out.println("key:value = " + k + ":" + v)
//        );
//
//    }



}
